package cn.lingyangwl.agile.model.module.auth;

import cn.lingyangwl.agile.model.constants.TenantCons;
import cn.lingyangwl.agile.model.enums.RoleEnum;
import lombok.Data;
import lombok.experimental.Accessors;

import java.io.Serializable;
import java.util.*;

/**
 * 用户在某个租户下的相关数据
 * @author shenguangyang
 */
@Data
@Accessors(chain = true)
public class AuthUserTenant implements Serializable {
    private static final long serialVersionUID = -6382972526573193470L;
    /**
     * 主租户id
     */
    private String mainTenantId = "-1";

    /**
     * 当前租户id, 现在采用前端传递的值, 之前是当前端切换租户后, 就直接采用缓存中存放的最后一次租户id,
     * 但是, 当想要实现在主租户中查看各个子租户数据时, 会有问题, 所以这里现在改成从前端请求头中取, 为了保证安全,
     * 需要校验租户是否越权, 在切换租户时候, 已经把用户所拥有的所有租户id存入到缓存中, 每次请求都校验请求头中的租户id
     * 是否在所拥有租户id列表中
     *
     * @see LoginUser#getOwningTenantIds()
     */
    private String tenantId = "-1";

    /**
     * 是否为系统管理租户(平台端)
     */
    private Boolean isSysAdmin = Boolean.FALSE;

    /**
     * 是否为管理租户类型(用于管理某一个场景)
     */
    private Boolean isMgtScene = Boolean.FALSE;

    /**
     * 是否为所在租户的拥有者
     */
    private Boolean isOwner;

    /**
     * 管理场景租户id
     */
    private String mgtSceneTenantId;

    /**
     * 用户角色编码
     */
    private List<String> roleCodes = Collections.emptyList();

    /**
     * 用户部门
     */
    private Set<Long> deptIds = Collections.emptySet();

    /**
     * 是否为租户拥有者
     */
    public Boolean owner() {
        return roleCodes.contains(RoleEnum.OWNER.getCode());
    }

    /**
     * 判断当前租户是否为主租户
     * @return true 主
     */
    public boolean mainTenant() {
        return mainTenant(mainTenantId, tenantId);
    }

    public static boolean mainTenant(String mainTenantId, String tenantId) {
        String mainId = Optional.ofNullable(mainTenantId).orElse("=1");
        String id = Optional.ofNullable(tenantId).orElse("-2");
        return mainId.compareTo(id) == 0;
    }

    public static boolean mainTenant(Long mainTenantId, Long tenantId) {
        Long mainId = Optional.ofNullable(mainTenantId).orElse(-1L);
        Long id = Optional.ofNullable(tenantId).orElse(-2L);
        return mainId.compareTo(id) == 0;
    }

    public String getMainTenantId() {
        return Objects.equals(mainTenantId, "-1") ? tenantId : mainTenantId;
    }

    public Boolean getIsMgtScene() {
        return getIsSysAdmin() || isMgtScene;
    }

    public Boolean getIsSysAdmin() {
        this.isSysAdmin = TenantCons.SYSTEM_TENANT_ID.equals(tenantId);
        return this.isSysAdmin;
    }
}
